"""Support methods for a hexagon based system with three axis

Main goal of this system is to make all hexagon operations
equal through the system.

This coordinate system is based on axis going through the corners of
a hexagon.
  -y
 /  \
-x  +z
|    |
-z  +x
 \  /
  +x
"""

#              a, b, c
ORIGO      = ( 0, 0, 0)
RIGHT      = ( 1, 0, 1)
DOWN_RIGHT = ( 1, 1, 0)
DOWN_LEFT  = ( 0, 1,-1)
LEFT       = (-1, 0,-1)
UP_LEFT    = (-1,-1, 0)
UP_RIGHT   = ( 0,-1, 1)
DIFFERENCE = [RIGHT, DOWN_RIGHT, DOWN_LEFT, LEFT, UP_LEFT, UP_RIGHT]

def add(left, right):
    return tuple(map(lambda x, y: x + y, left, right))

def diff(left, right):
    return tuple(map(lambda x, y: x - y, left, right))

def create_list(radius):
    """Create a list of all hexagons within certain radius
    
    Radius = 0 => 1 hexagon

    """

    result = []
    hex = ORIGO
    result.append(hex)
    for r in range(1, radius + 1):
        hex = add(hex, UP_LEFT)
        for d in range(0, len(DIFFERENCE)):
            for i in range(0, r):
                hex = add(hex, DIFFERENCE[d])
                result.append(hex)
    return result

def get_hex(a, b, c):
    """Calculate integer hexagon from a floating point

    """

    da = abs(a - round(a))
    db = abs(b - round(b))
    dc = abs(c - round(c))

    if da < db and da < dc:
        A = round(a);
        if db < dc:
            B = round(b)
            C = A - B
        else:
            C = round(c)
            B = A - C
    elif db < da and db < dc:
        B = round(b)
        if da < dc:
            A = round(a)
            C = A - B
        else:
            C = round(c)
            A = B + C
    else:
        C = round(c)
        if da < db:
            A = round(a)
            B = A - C
        else:
            B = round(b)
            A = B + C
    return (int(A), int(B), int(C))

def get_neighbours(hex):
    result = []
    for direction in DIFFERENCE:
        result.append(add(hex, direction))
    return result

def get_distance(source, destination):
    max = 0
    for i in range(0, 3):
        result = abs(destination[i] - source[i])
        if result > max:
            max = result
    return max
